#include "stdafx.h"
#include "caRStream.h"

void caCRStreamBuf::_Init()
{
	if(m_alloc!=NULL)
	{
		try
		{
			if(m_raddr==NULL)
			{
				m_raddr=m_alloc->GetMemory(m_size);
				if(m_raddr!=NULL)
				{
					m_risa=true;
				}
			}
			if((m_raddr!=NULL)&&(m_laddr==NULL))
			{
				m_laddr=new char[m_size];
				if(m_laddr!=NULL)
				{
					m_lisa=true;
				}
			}
			setg((char*)m_laddr,(char*)m_laddr,(char*)m_laddr);
			setp((char*)m_laddr,(char*)((size_t)m_laddr+m_size));
		}
		catch(...)
		{
		}
	}
	else
	{
		setg(NULL,NULL,NULL);
		setp(NULL,NULL,NULL);
		m_laddr=NULL;
		m_raddr=NULL;
	}
}
caCRStreamBuf::caCRStreamBuf(caIRMemAllocater* alloc,caIRMemReadWrite* rwctrl,int bufsize,void*raddr,void* laddr,bool rput)
	:strstreambuf(0)
{
	m_alloc=alloc;
	m_rwctrl=rwctrl;

	m_raddr=raddr;
	m_laddr=laddr;

	m_size=bufsize;

	m_direc=rput;
	m_risa=false;
	m_lisa=false;
	_Init();
}

caCRStreamBuf::caCRStreamBuf(caIProcCtrl* pctrl,int bufsize,void*raddr,void* laddr,bool rput)
{
	m_alloc=pctrl->GetRMemAllocater();
	m_rwctrl=pctrl->GetRMemReadWrite();

	m_raddr=raddr;
	m_laddr=laddr;

	m_size=bufsize;

	m_direc=rput;
	m_risa=false;
	m_lisa=false;
	_Init();
}

caCRStreamBuf::~caCRStreamBuf()
{
	if(m_alloc!=NULL)
	{
		try
		{
			if(m_laddr&&m_lisa) delete m_laddr;
			if(m_raddr&&m_risa) m_alloc->FreeMemory(m_raddr);
		}
		catch(...)
		{
		}
	}
}

void* caCRStreamBuf::GetRAddress()
{
	return m_raddr;
}

void* caCRStreamBuf::GetLAddress()
{
	return m_laddr;
}

bool caCRStreamBuf::SetDirectional(bool rput)
{
	bool tmp=m_direc;
	m_direc=rput;
	return tmp;
}

int caCRStreamBuf::sync()
{
	try
	{
		if(m_rwctrl)
		{
			if(m_direc)
			{
				unsigned long len=m_rwctrl->Write(m_raddr,m_laddr,m_size);
				if(len==0)
					return -1;
				else
					return len;
			}
			else
			{
				unsigned long len=m_rwctrl->Read(m_raddr,m_laddr,m_size);
				if(len==0)
					return -1;
				else
					return len;
			}
		}
	}
	catch (...)
	{
	}
	return 0;
}

caCRStream::caCRStream(caIRMemAllocater* alloc,caIRMemReadWrite* rwctrl,int bufsize,void*raddr,void* laddr)
	: iostream(&_Mysb),_Mysb(alloc,rwctrl,bufsize,raddr,laddr)
{
	if((_Mysb.GetRAddress()==NULL)||(_Mysb.GetLAddress()==NULL))
	{
		setstate(badbit);
	}
}

caCRStream::caCRStream(caIProcCtrl* pctrl,int bufsize,void*raddr,void* laddr)
: iostream(&_Mysb),_Mysb(pctrl,bufsize,raddr,laddr)
{
	if((_Mysb.GetRAddress()==NULL)||(_Mysb.GetLAddress()==NULL))
	{
		setstate(badbit);
	}
}

caCRStream::~caCRStream()
{
}

strstreambuf* caCRStream::rdbuf() const
{
	return ((strstreambuf *)&_Mysb);
}

void caCRStream::freeze(bool _Freezeit)
{
	_Mysb.freeze(_Freezeit);
}

char* caCRStream::str()
{
	return (_Mysb.str());
}

streamsize caCRStream::pcount() const
{
	return (_Mysb.pcount());
}

void* caCRStream::GetCurrRAddr()
{
	void* raddr=_Mysb.GetRAddress();
	void* laddr=_Mysb.GetLAddress();
	if((raddr!=NULL)&&(laddr!=NULL)&&(!fail()))
	{
		return (void*)(size_t(raddr)+tellp());
	}
	return NULL;
}

void* caCRStream::GetCurrLAddr()
{
	void* raddr=_Mysb.GetRAddress();
	void* laddr=_Mysb.GetLAddress();
	if((raddr!=NULL)&&(laddr!=NULL)&&(!fail()))
	{
		return (void*)(size_t(laddr)+tellp());
	}
	return NULL;
}

caCRStream::operator caRAddress()
{
	return caRAddress(GetCurrRAddr());
}

caCRStream::operator caLAddress()
{
	return caLAddress(GetCurrLAddr());
}

bool caCRStream::SetDirectional(bool direc)
{
	return _Mysb.SetDirectional(direc);
}

